package grav;

import static mathUtils.VecMath.*;
import processing.core.PApplet;
import integration.*;

@SuppressWarnings("serial")
public class GravFlakeDemo extends PApplet {
	float graphicsScale = 5f;
	int numFlakes = 100;
	float timeStep = 0.02f;
	float stepsPerFrame = 5;
	GravLump sun;
	GravFlake fl[];

	GravFlakeSystem sys;
	Integrator rk4;
	
	public void setup() {
		size(600, 600);
		smooth();
		
		sun = new GravLump(this, 100f, 2f, 0, 0);

		fl = new GravFlake[numFlakes];
		float x[] = new float[2];
		float v[] = new float[2];
		for (int i =0; i<numFlakes; ++i) {
			float mass = 0.001f*random(0.25f, 1f);
			float radius = sqrt(10000*mass);
			float ang = random(0, 2*PI);
			float r = 0.25f*width/graphicsScale*random(0.125f, 1f);
			vecUnitByAngle(ang, x);
			vecScale(x, r);
			vecUnitByAngle(ang+PI/2, v);
			vecScale(v, sqrt(sun.gravMass()*1.0f/r));
			GravFlake f = new GravFlake(this, mass, radius, x[0], x[1],
					v[0], v[1]);
			fl[i] = f;
		}
		
		sys = new GravFlakeSystem();
		sys.addGravLump(sun);
		for (GravFlake f : fl) sys.addGravFlake(f);
		
		rk4 = new RungeKutta4(sys);
		rk4.findSlope();
		
	}
	
	void advance() {
		rk4.finalizeSlope(timeStep);
		rk4.takeFinalStep(timeStep);
		rk4.findSlope();
	}
	
	public void draw() {

		for (int i = 0; i < stepsPerFrame; ++i) advance();
		
		translate(width/2, height/2);
		scale(graphicsScale, -graphicsScale);
		background(0,0,0);
		
		for (GravFlake f: fl) f.draw();
		sun.draw();
	}
}
